/**
 * 快递公司识别工具
 * 根据快递单号格式识别快递公司
 */

class ExpressCompanyDetector {
  // 快递公司数据库
  static companies = [
    {
      code: 'SF',
      name: '顺丰速运',
      pattern: /^(SF|sf)\d{12}$/i,
      logo: '🚀',
      smsKeywords: ['顺丰', 'SF']
    },
    {
      code: 'ZTO',
      name: '中通快递',
      pattern: /^\d{12,13}$/,
      logo: '📦',
      smsKeywords: ['中通', 'ZTO']
    },
    {
      code: 'YTO',
      name: '圆通速递',
      pattern: /^\d{12,13}$/,
      logo: '🔵',
      smsKeywords: ['圆通', 'YTO']
    },
    {
      code: 'STO',
      name: '申通快递',
      pattern: /^\d{12,13}$/,
      logo: '🟡',
      smsKeywords: ['申通', 'STO']
    },
    {
      code: 'YD',
      name: '韵达快递',
      pattern: /^\d{13}$/,
      logo: '🟢',
      smsKeywords: ['韵达', 'YD', 'YUNDA']
    },
    {
      code: 'BEST',
      name: '百世快递',
      pattern: /^\d{12,13}$/,
      logo: '🟣',
      smsKeywords: ['百世', 'BEST']
    },
    {
      code: 'EMS',
      name: '邮政EMS',
      pattern: /^[A-Z]{2}\d{9}[A-Z]{2}$/,
      logo: '📮',
      smsKeywords: ['EMS', '邮政', '中国邮政']
    },
    {
      code: 'JD',
      name: '京东物流',
      pattern: /^(JD|jd)\d{13,15}$/i,
      logo: '🐶',
      smsKeywords: ['京东', 'JD']
    },
    {
      code: 'DBL',
      name: '德邦快递',
      pattern: /^\d{12,15}$/,
      logo: '🚚',
      smsKeywords: ['德邦', 'DBL']
    },
    {
      code: 'HHTT',
      name: '天天快递',
      pattern: /^\d{12,14}$/,
      logo: '⚡',
      smsKeywords: ['天天', 'HHTT']
    }
  ];

  /**
   * 根据单号识别快递公司
   * @param {string} trackingNumber - 快递单号
   * @returns {Object|null} 快递公司信息
   */
  static detect(trackingNumber) {
    if (!trackingNumber || typeof trackingNumber !== 'string') {
      return null;
    }

    const number = trackingNumber.trim();

    // 优先匹配特殊格式（如顺丰、EMS、京东）
    const specialCompanies = this.companies.filter(c => 
      c.code === 'SF' || c.code === 'EMS' || c.code === 'JD'
    );

    for (const company of specialCompanies) {
      if (company.pattern.test(number)) {
        return { ...company };
      }
    }

    // 匹配其他快递公司（通用格式）
    const generalCompanies = this.companies.filter(c => 
      c.code !== 'SF' && c.code !== 'EMS' && c.code !== 'JD'
    );

    for (const company of generalCompanies) {
      if (company.pattern.test(number)) {
        return { ...company };
      }
    }

    return null;
  }

  /**
   * 根据短信内容识别快递公司
   * @param {string} smsContent - 短信内容
   * @returns {Object|null} 快递公司信息
   */
  static detectFromSMS(smsContent) {
    if (!smsContent || typeof smsContent !== 'string') {
      return null;
    }

    const content = smsContent.toLowerCase();

    for (const company of this.companies) {
      for (const keyword of company.smsKeywords) {
        if (content.includes(keyword.toLowerCase())) {
          return { ...company };
        }
      }
    }

    return null;
  }

  /**
   * 获取所有支持的快递公司
   * @returns {Array<Object>} 快递公司列表
   */
  static getAllCompanies() {
    return this.companies.map(c => ({ ...c }));
  }

  /**
   * 根据代码获取快递公司
   * @param {string} code - 快递公司代码
   * @returns {Object|null} 快递公司信息
   */
  static getCompanyByCode(code) {
    const company = this.companies.find(c => c.code === code);
    return company ? { ...company } : null;
  }

  /**
   * 验证单号格式
   * @param {string} trackingNumber - 快递单号
   * @param {string} companyCode - 快递公司代码
   * @returns {boolean} 是否有效
   */
  static validate(trackingNumber, companyCode) {
    if (!trackingNumber || !companyCode) {
      return false;
    }

    const company = this.getCompanyByCode(companyCode);
    if (!company) {
      return false;
    }

    return company.pattern.test(trackingNumber.trim());
  }

  /**
   * 从文本中提取快递信息（单号和公司）
   * @param {string} text - 文本内容（短信或其他）
   * @returns {Object|null} { trackingNumber, company }
   */
  static extractExpressInfo(text) {
    if (!text || typeof text !== 'string') {
      return null;
    }

    // 先识别快递公司
    const company = this.detectFromSMS(text);

    // 提取可能的快递单号
    const patterns = [
      /SF\d{12}/gi,
      /[A-Z]{2}\d{9}[A-Z]{2}/g,
      /JD\d{13,15}/gi,
      /\d{12,15}/g
    ];

    for (const pattern of patterns) {
      const matches = text.matchAll(pattern);
      for (const match of matches) {
        const trackingNumber = match[0];
        
        // 如果已经识别出公司，验证单号是否匹配
        if (company) {
          if (this.validate(trackingNumber, company.code)) {
            return {
              trackingNumber,
              company
            };
          }
        } else {
          // 如果没有识别出公司，尝试通过单号识别
          const detectedCompany = this.detect(trackingNumber);
          if (detectedCompany) {
            return {
              trackingNumber,
              company: detectedCompany
            };
          }
        }
      }
    }

    return null;
  }
}

export default ExpressCompanyDetector;
